package com.logic.landseaserver.models.refunddiary.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.logic.common.security.SecurityUtils;
import com.logic.common.util.QueryUtil;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.config.FileConfiguration;
import com.logic.landseaserver.common.enums.BillTypeEnum;
import com.logic.landseaserver.common.exception.LandseaBusinessException;
import com.logic.landseaserver.common.util.DateUtil;
import com.logic.landseaserver.models.refunddiary.bean.FeeTypeResp;
import com.logic.landseaserver.models.refunddiary.bean.RefundDetailResp;
import com.logic.landseaserver.models.refunddiary.bean.RefundRecordResp;
import com.logic.landseaserver.persistence.read.BillReadMapper;
import com.logic.landseaserver.persistence.read.RefundReadMapper;




@Service
public class RefundDiaryService implements EnvironmentAware
{
    private static final String ENV_FILE_PATH = "logic.file.path.";
    
    private static final String EXCEL_PATH = "excelPath";
    
    private static final String REMOTE_PATH = "remote";
    
    private static RelaxedPropertyResolver propertyResolver;
    
    private static final Logger logger = LoggerFactory.getLogger(RefundDiaryService.class);
    
    @Autowired
    private RefundReadMapper refundReadMapper;
    
    @Autowired
    private FileConfiguration fileConfiguration;
    
    @Autowired
    private BillReadMapper billReadMapper;
    
    
    public List<RefundRecordResp> getRefundRecordList(QueryUtil queryUtil) throws LandseaBusinessException
    {
        Integer systemId = SecurityUtils.getCurrentLogin().getUserId();
        if (systemId == null)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.TOKEN_IS_NULL);
        }
        Map<String, Object> params = queryUtil.getParams();
        params.put("userId", systemId);
        List<RefundRecordResp> resp = refundReadMapper.getRefundRecord(queryUtil);
        return resp;
    }
    
    public String downloadRefundRecordExcel(QueryUtil queryUtil) throws Exception
    {
        StringBuffer url = propertyResolver.getProperty(REMOTE_PATH, StringBuffer.class, null);
        StringBuffer excelpath = propertyResolver.getProperty(EXCEL_PATH, StringBuffer.class, null);
        
        InputStream ins = null;
        Workbook wb = null;
        try
        {
            ins = RefundDiaryService.class.getClassLoader().getResourceAsStream("退款日报表.xlsx");
            wb = WorkbookFactory.create(ins);
        }
        catch (Exception e)
        {
            logger.error("exportPropertyList error.", e);
        }
        finally
        {
            try
            {
                ins.close();
            }
            catch (IOException e)
            {
                logger.error("exportPropertyList error.", e);
            }
        }
        //查出退款记录
        Integer systemId = SecurityUtils.getCurrentLogin().getUserId();
        if (systemId == null)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.TOKEN_IS_NULL);
        }
        Map<String, Object> params = queryUtil.getParams();
        params.put("userId", systemId);
        List<RefundRecordResp> list = refundReadMapper.getRefundRecord(queryUtil);
        //往excel里面存值
        if (list != null && list.size() > 0)
        {
            Sheet sheet = wb.getSheet("退款日报表");
            // 生成一个样式
            CellStyle style = wb.createCellStyle();
            // 设置这些样式
            style.setAlignment(CellStyle.ALIGN_CENTER);
            // 生成一个字体
            Font font = wb.createFont();
            font.setFontHeightInPoints((short)9);
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
            // 把字体应用到当前的样式
            style.setFont(font);
            
            Row row;
            DecimalFormat df = new DecimalFormat("0.00");
            int startRow = 2;
            for (int i = 0; i < list.size(); i ++)
            {
                RefundRecordResp object = list.get(i);
                row = sheet.createRow(startRow);
                //序号
                row.createCell(0).setCellValue(i + 1);
                // 公司名 即地区
                row.createCell(1).setCellValue(object.getAreaCodeZH() == null ? "" : object.getAreaCodeZH());
                //门店即项目名
                row.createCell(2).setCellValue(object.getPrjName() == null ? "" : object.getPrjName());
                //退房类型
                row.createCell(3).setCellValue(object.getOffrentType() == null ? "" : object.getOffrentType());
                //客户姓名
                row.createCell(4).setCellValue(object.getCertificatesName() == null ? "" : object.getCertificatesName());
                //实际退款人几持卡人名
                row.createCell(5).setCellValue(object.getCardUserName() == null ? "" : object.getCardUserName());
                //退款类型
                row.createCell(6).setCellValue(object.getRefundType() == null ? "" : object.getRefundType());
                //退款金额
                row.createCell(7).setCellValue(object.getRefundAmount() == null ? "" : df.format(object.getRefundAmount()));
                if (null == object.getBillId() || object.getBillId() == 0)
                {
                    row.createCell(8).setCellValue("");
                    row.createCell(9).setCellValue("");
                    row.createCell(10).setCellValue("");
                    row.createCell(11).setCellValue("");
                    row.createCell(12).setCellValue("");
                    row.createCell(13).setCellValue("");
                    row.createCell(14).setCellValue("");
                    row.createCell(15).setCellValue("");
                    row.createCell(16).setCellValue("");
                    row.createCell(17).setCellValue("");
                    row.createCell(18).setCellValue("");
                    row.createCell(19).setCellValue("");
                    row.createCell(20).setCellValue("");
                    row.createCell(21).setCellValue("");
                    row.createCell(22).setCellValue("");
                }
                else
                {
                    //查询出未减免的退房费项
                    List<RefundDetailResp> detailResps = billReadMapper.getRefundDetail(object.getBillId());
                    //查出用过授权码的费项
                    List<RefundDetailResp> usedCouponDetailResps = billReadMapper.getUsedCouponRefundDetail(object.getBillId());
                    Double relifMoney = 0.00;
                    if (CollectionUtils.isNotEmpty(usedCouponDetailResps))
                    {
                        for (RefundDetailResp refundDetailResp : usedCouponDetailResps)
                        {
                            relifMoney += refundDetailResp.getMoney();
                        }
                        //其他优惠减免
                        row.createCell(22).setCellValue(relifMoney == null ? "" : df.format(relifMoney));
                    }
                    if (CollectionUtils.isEmpty(detailResps))
                    {
                        continue;
                    }
                    FeeTypeResp feeTypeResp = new FeeTypeResp();
                    for (RefundDetailResp refundDetailResp : detailResps)
                    {
                        //房租
                        if (BillTypeEnum.CTBI8.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI8(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //服务费
                        else if (BillTypeEnum.CTBI9.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI9(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //房间押金
                        else if (BillTypeEnum.CTBI11.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI11(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //水费押金
                        else if (BillTypeEnum.CTBI10.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI10(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }                     
                        //水费
                        else if (BillTypeEnum.CTBI1.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI1(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //电费
                        else if (BillTypeEnum.CTBI2.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI2(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //燃气费
                        else if (BillTypeEnum.CTBI3.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI3(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //热水费
                        else if (BillTypeEnum.CTBI4.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI4(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //停车费
                        else if (BillTypeEnum.CTBI5.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI5(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //空调费
                        else if (BillTypeEnum.CTBI6.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI6(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //采暖费
                        else if (BillTypeEnum.CTBI7.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI7(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //其他
                        else if (BillTypeEnum.CTBI12.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI12(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //滞纳金
                        else  if (BillTypeEnum.CTBI13.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI13(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        //违约金
                        else if (BillTypeEnum.CTBI14.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI14(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }
                        // 账户余额
                        else if (BillTypeEnum.CTBI22.getCode().equals(refundDetailResp.getFeeTypeCode()))
                        {
                            feeTypeResp.setCTBI22(refundDetailResp.getMoney() == null ? "" : df.format(refundDetailResp.getMoney()));
                        }                        
                        row.createCell(8).setCellValue(feeTypeResp.getCTBI8());
                        row.createCell(9).setCellValue(feeTypeResp.getCTBI9());
                        row.createCell(10).setCellValue(feeTypeResp.getCTBI11());
                        row.createCell(11).setCellValue(feeTypeResp.getCTBI10());
                        row.createCell(12).setCellValue(feeTypeResp.getCTBI1());
                        row.createCell(13).setCellValue(feeTypeResp.getCTBI2());
                        row.createCell(14).setCellValue(feeTypeResp.getCTBI3());
                        row.createCell(15).setCellValue(feeTypeResp.getCTBI4());
                        row.createCell(16).setCellValue(feeTypeResp.getCTBI5());
                        row.createCell(17).setCellValue(feeTypeResp.getCTBI6());
                        row.createCell(18).setCellValue(feeTypeResp.getCTBI7());
                        row.createCell(19).setCellValue(feeTypeResp.getCTBI12());
                        row.createCell(20).setCellValue(feeTypeResp.getCTBI13());
                        row.createCell(21).setCellValue(feeTypeResp.getCTBI14());
                        row.createCell(22).setCellValue(feeTypeResp.getCTBI22());
                        
                        // 其他优惠减免，暂时没有
                        //row.createCell(23).setCellValue("");
                    }
                }
                
                //申请时间
                row.createCell(24).setCellValue(object.getApplyDate() == null ? "" : DateUtil.convertDateTime(object.getApplyDate()));
                //退款时间
                row.createCell(25).setCellValue(object.getRefundDate() == null ? "" : DateUtil.convertDateTime(object.getRefundDate()));
                //退款状态
                row.createCell(26).setCellValue(object.getStatus() == null ? "" : object.getStatus());
                //退款当前节点
                row.createCell(27).setCellValue(object.getCurrentZH() == null ? "" : object.getCurrentZH());
                //合同编号
                row.createCell(28).setCellValue(object.getContractNo() == null ? "" : object.getContractNo());
                //房间编号
                row.createCell(29).setCellValue(object.getHouseNum() == null ? "" : object.getHouseNum());
                //付款方式
                row.createCell(30).setCellValue(object.getPaymentMode() == null ? "" : object.getPaymentMode());
                //合同期间起始日
                row.createCell(31).setCellValue(object.getInDate() == null ? "" : DateUtil.convertDate(object.getInDate()));
                //终止日
                row.createCell(32).setCellValue(object.getOutDate() == null ? "" : DateUtil.convertDate(object.getOutDate()));
                //合同约定 住宿费
                row.createCell(33).setCellValue(object.getRentPrice() == null ? "" : df.format(object.getRentPrice()));
                //押金
                row.createCell(34).setCellValue(object.getDepositPrice() == null ? "" : df.format(object.getDepositPrice()));
                //服务费
                row.createCell(35).setCellValue(object.getPropertyFee() == null ? "" : df.format(object.getPropertyFee()));
                //退房原因
                row.createCell(36).setCellValue(object.getOffrentReason() == null ? "" : object.getOffrentReason());
                //备注
                row.createCell(37).setCellValue(object.getRemark() == null ? "" : object.getRemark());
                
                startRow = startRow + 1;
            }
        }
        OutputStream fos = null;
        try
        {
            Integer userId = SecurityUtils.getCurrentLogin().getUserId();
            String filepath = fileConfiguration.getLocal() + "/" + excelpath;
            // String filepath = "C://work";
            File file = new File(filepath);
            // 如果文件夹不存在则创建
            if (!file.exists() && !file.isDirectory())
            {
                file.mkdir();
            }
            // 删除userId开头的excel
            String[] files = file.list(new FilenameFilter()
            {
                @Override
                public boolean accept(File dir, String name)
                {
                    return name.endsWith(".xlsx");
                }
            });
            for (String f : files)
            {
                if (f.startsWith(userId + "-"))
                {
                    new File(filepath + "/" + f).delete();
                }
            }
            
            Date nowTime = new Date(System.currentTimeMillis());
            SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
            String time = sdFormatter.format(nowTime);
            
            String fileName = "退款日报表_" + time +".xlsx";
            fos = new FileOutputStream(filepath + "/" + fileName);
            wb.write(fos);
            
            StringBuffer returnUrl = new StringBuffer();
            returnUrl.append(url);
            returnUrl.append("/");
            returnUrl.append(excelpath);
            returnUrl.append("/");
            returnUrl.append(fileName);
            return returnUrl.toString();
        }
        catch (Exception e)
        {
            logger.error("exportPropertyList error.", e);
            return null;
        }
        finally
        {
            try
            {
                fos.flush();
                fos.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    @Override
    public void setEnvironment(Environment environment)
    {
        propertyResolver = new RelaxedPropertyResolver(environment, ENV_FILE_PATH);
    }
    
}
